package com.admin.service.impl;

import java.util.*;


import com.admin.common.enums.MemberLevelEnum;
import com.admin.common.exception.BizException;
import com.admin.domain.AdminDO;
import com.admin.mapper.AdminMapper;
import com.admin.service.RegionsService;
import jakarta.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.admin.common.enums.EnumResult;
import com.admin.common.shiro.ShiroUtils;
import com.admin.common.util.YsCollectionUtil;
import com.admin.domain.RoleDO;
import com.admin.mapper.AdminRoleMapper;
import com.admin.mapper.RoleMapper;
import com.admin.mapper.RoleMenuMapper;
import com.admin.service.MenuService;
import com.admin.service.RoleService;
import com.admin.service.TransactionService;
import com.admin.vo.PageVO;
import com.admin.vo.ResultVO;
import com.admin.vo.SimpleResultVO;
import com.admin.vo.system.ListRoleVO;
import com.admin.vo.system.RoleSelectedVO;

@Service
public class RoleServiceImpl extends BaseServiceImpl<RoleDO> implements RoleService {

    @Autowired
    private TransactionService transactionService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private RegionsService regionsService;

    @PostConstruct
    private void init() {
        setBaseMapper(roleMapper);
    }

    @Override
    public String findByUserId(Integer userId) {
        List<RoleDO> roleDOList = roleMapper.findByUserId(userId);
        if (!CollectionUtils.isEmpty(roleDOList) && roleDOList.size() >0) {
            if (null != roleDOList.get(0).getBusinessAreaId()) {
                return roleDOList.get(0).getBusinessAreaId().toString();
            }
        }
        return null;
    }

    @Override
    public RoleDO findRoleLevelByUserId(Integer userId) {
        List<RoleDO> roleDOList = roleMapper.findByUserId(userId);
        if (!CollectionUtils.isEmpty(roleDOList)) {
            return roleDOList.get(0);
        }
        return null;
    }

    @Override
    public SimpleResultVO deleteByPrimaryKeys(List<Long> list) {
        SimpleResultVO result = new SimpleResultVO();
        if (CollectionUtils.isEmpty(list)) {
            result.setCode(EnumResult.PARAM_NULL.getCode());
            result.setMsg(EnumResult.PARAM_NULL.getMsg());
            return result;
        }

        transactionService.deleteRoles(list);
        ShiroUtils.clearAllCachedAuthorization();

        result.setCode(EnumResult.SUCCESS.getCode());
        result.setMsg(EnumResult.SUCCESS.getMsg());
        return result;
    }

    @Override
    public SimpleResultVO deleteByPrimaryKey(Long roleId) {
        SimpleResultVO result = new SimpleResultVO();
        if (roleId == null) {
            result.setCode(EnumResult.PARAM_NULL.getCode());
            result.setMsg(EnumResult.PARAM_NULL.getMsg());
            return result;
        }

        transactionService.deleteRole(roleId);
        ShiroUtils.clearAllCachedAuthorization();

        result.setCode(EnumResult.SUCCESS.getCode());
        result.setMsg(EnumResult.SUCCESS.getMsg());
        return result;
    }

    /**
     * 角色列表
     *
     * @param pageIndex
     * @param pageSize
     * @param params
     * @return
     */
    @Override
    public ResultVO<PageVO<ListRoleVO>> getPageList(Integer pageIndex, Integer pageSize, Map<String, Object> params) {
        ResultVO<PageVO<ListRoleVO>> result = new ResultVO<>();
        //市/区县 看自己以及下属
        if (!ShiroUtils.getMemberLevel().equals(MemberLevelEnum.PROVINCE.getKey())) {
            List<Integer> businessRoles = regionsService.findChildrens(ShiroUtils.getUser().getBusinessAreaIds());
            if (!CollectionUtils.isEmpty(businessRoles) && businessRoles.size() > 0) {
                params.put("businessAreaIds",businessRoles);
            }
        }
        PageVO<ListRoleVO> page = new PageVO<>(pageIndex, pageSize);
        Integer totalCount = roleMapper.countByMap(params);
        page.setTotalCount(totalCount);
        if (totalCount > 0) {
            params.put("startIndex", page.getStartIndex());
            params.put("pageSize", page.getPageSize());
            List<RoleDO> roleDOs = roleMapper.selectByMap(params);
            page.setData(YsCollectionUtil.copyList(roleDOs, ListRoleVO.class));
        }
        result.setData(page);
        result.setCode(EnumResult.SUCCESS.getCode());
        result.setMsg(EnumResult.SUCCESS.getMsg());
        return result;
    }

    @Override
    public ResultVO<List<RoleSelectedVO>> getSelectRoles() {

        ResultVO<List<RoleSelectedVO>> resultVO = new ResultVO<List<RoleSelectedVO>>();

        List<RoleSelectedVO> roleSelectedVOs = new ArrayList<RoleSelectedVO>();
        Map<String, Object> params = YsCollectionUtil.createHashMap();
        List<RoleDO> roleDOs = roleMapper.selectByMap(params);
        for (RoleDO roleDO : roleDOs) {
            RoleSelectedVO roleSelectedVO = new RoleSelectedVO();
            roleSelectedVO.setRoleId(roleDO.getRoleId());
            roleSelectedVO.setRoleName(roleDO.getRoleName());
            roleSelectedVO.setIsSelected(false);
            roleSelectedVOs.add(roleSelectedVO);
        }

        resultVO.setData(roleSelectedVOs);
        resultVO.setCode(EnumResult.SUCCESS.getCode());
        resultVO.setMsg(EnumResult.SUCCESS.getMsg());
        return resultVO;
    }

    /**
     * 查询区域下符合的去角色
     * @param areaIds
     * @param type
     * @return
     */
    @Override
    public ResultVO<List<RoleSelectedVO>> getSelectRolesByAreaId(String areaIds, Integer type, Integer userId) {
        if (StringUtils.isEmpty(areaIds)) {
            return null;
        }
        List<Integer> areaIdsArray = new ArrayList<>();
        String[] str = areaIds.split(",");
        for (String s : str) {
            if (StringUtils.isEmpty(s)) {
                continue;
            }
            areaIdsArray.add(Integer.parseInt(s));
        }
        ResultVO<List<RoleSelectedVO>> resultVO = new ResultVO<>();
        List<RoleSelectedVO> roleSelectedVOs = new ArrayList<>();
        Map<String, Object> params = YsCollectionUtil.createHashMap();
        params.put("orderBy", "role_id");

        if (type != null && type == 0) {
            params.put("roleName", "申报管理");
        } else {
            params.put("businessAreaIds", areaIdsArray);
        }
        //如果自己拥有的 ，选中
        List<Long> roleIds = adminRoleMapper.getRoleIdsByUserId(userId);
        List<RoleDO> roleDOs = roleMapper.selectByMap(params);
        for (RoleDO roleDO : roleDOs) {
            if (ShiroUtils.getUserId() != 1) {
                if (roleDO.getRoleId() == 1) {
                    continue;
                }
            }
            RoleSelectedVO roleSelectedVO = new RoleSelectedVO();
            roleSelectedVO.setRoleId(roleDO.getRoleId());
            roleSelectedVO.setRoleName(roleDO.getRoleName());
            roleSelectedVO.setIsSelected(false);
            if (roleIds != null && roleIds.contains(roleDO.getRoleId())) {
                roleSelectedVO.setIsSelected(true);
            }

            roleSelectedVOs.add(roleSelectedVO);
        }
        resultVO.setData(roleSelectedVOs);
        resultVO.setCode(EnumResult.SUCCESS.getCode());
        resultVO.setMsg(EnumResult.SUCCESS.getMsg());
        return resultVO;
    }

    @Override
    public ResultVO<List<RoleSelectedVO>> getSelectRoles(Integer userId) {
        ResultVO<List<RoleSelectedVO>> resultVO = new ResultVO<List<RoleSelectedVO>>();
        if (userId == null) {
            resultVO.setCode(EnumResult.PARAM_NULL.getCode());
            resultVO.setMsg(EnumResult.PARAM_NULL.getMsg());
            return resultVO;
        }

        AdminDO adminDO = adminMapper.selectByPrimaryKey(userId);
        String businessAreaIds = adminDO.getBusinessAreaIds();
        if (StringUtils.isEmpty(businessAreaIds)) {
            resultVO.setCode(EnumResult.SUCCESS.getCode());
            resultVO.setMsg(EnumResult.SUCCESS.getMsg());
            return resultVO;
        }

        List<String> areaIdList = Arrays.asList(businessAreaIds.split(","));
        List<RoleSelectedVO> roleSelectedVOs = new ArrayList<RoleSelectedVO>();

        Map<String, Object> params = YsCollectionUtil.createHashMap();
        List<RoleDO> roleDOs = roleMapper.selectByMap(params);

        List<Long> roleIds = adminRoleMapper.getRoleIdsByUserId(userId);
        for (RoleDO roleDO : roleDOs) {
            if (Objects.nonNull(roleDO.getBusinessAreaId()) && !areaIdList.contains(roleDO.getBusinessAreaId())) {
                continue;
            }

            RoleSelectedVO roleSelectedVO = new RoleSelectedVO();
            roleSelectedVO.setRoleId(roleDO.getRoleId());
            roleSelectedVO.setRoleName(roleDO.getRoleName());
            if (roleIds.contains(roleDO.getRoleId())) {
                roleSelectedVO.setIsSelected(true);
            } else {
                roleSelectedVO.setIsSelected(false);
            }
            roleSelectedVOs.add(roleSelectedVO);
        }

        resultVO.setData(roleSelectedVOs);
        resultVO.setCode(EnumResult.SUCCESS.getCode());
        resultVO.setMsg(EnumResult.SUCCESS.getMsg());
        return resultVO;
    }

    @Override
    public SimpleResultVO saveRoleDO(RoleDO roleDO, List<Long> menuIds) {
        SimpleResultVO result = new SimpleResultVO();
        if (roleDO == null || CollectionUtils.isEmpty(menuIds)) {
            result.setCode(EnumResult.PARAM_NULL.getCode());
            result.setMsg(EnumResult.PARAM_NULL.getMsg());
            return result;
        }

        if (StringUtils.isEmpty(roleDO.getResponsibleAreaId())) {
            throw new BizException(-1, "请选择角色对应的区域");
        }

        ResultVO<Set<Long>> r = menuService.getParentIds(menuIds);
        if (!EnumResult.SUCCESS.getCode().equals(r.getCode())) {
            result.setCode(r.getCode());
            result.setMsg(r.getMsg());
            return result;
        }
        menuIds.addAll(r.getData());
        transactionService.saveRoleDO(roleDO, menuIds);

        result.setCode(EnumResult.SUCCESS.getCode());
        result.setMsg(EnumResult.SUCCESS.getMsg());
        return result;
    }

    @Override
    public SimpleResultVO upateRoleDO(RoleDO roleDO, List<Long> menuIds) {
        SimpleResultVO result = new SimpleResultVO();

        if (roleDO == null || roleDO.getRoleId() == null || CollectionUtils.isEmpty(menuIds)) {
            result.setCode(EnumResult.PARAM_NULL.getCode());
            result.setMsg(EnumResult.PARAM_NULL.getMsg());
            return result;
        }

        if (StringUtils.isEmpty(roleDO.getResponsibleAreaId())) {
            throw new BizException(-1, "请选择角色对应的区域");
        }

        ResultVO<Set<Long>> r = menuService.getParentIds(menuIds);
        if (!EnumResult.SUCCESS.getCode().equals(r.getCode())) {
            result.setCode(r.getCode());
            result.setMsg(r.getMsg());
            return result;
        }
        menuIds.addAll(r.getData());

        List<Long> exsitsMenuIds = roleMenuMapper.selectMenuIdByRoleId(roleDO.getRoleId());
        List<Long> temp = new ArrayList<Long>(exsitsMenuIds);

        exsitsMenuIds.removeAll(menuIds);
        menuIds.removeAll(temp);

        transactionService.updateRoleDO(roleDO, exsitsMenuIds, menuIds);

        if (!CollectionUtils.isEmpty(exsitsMenuIds) || !CollectionUtils.isEmpty(menuIds)) {
            ShiroUtils.clearAllCachedAuthorization();
        }

        result.setCode(EnumResult.SUCCESS.getCode());
        result.setMsg(EnumResult.SUCCESS.getMsg());
        return result;
    }

}
